package cn.unknowpupil.init.exceptions;

;

import cn.unknowpupil.init.common.enums.ResultStatus;
import cn.unknowpupil.init.common.resopnse.ResultResponse;
import cn.unknowpupil.init.utils.CharUtil;
import cn.unknowpupil.init.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.net.ConnectException;
import java.sql.SQLException;

/**
 * Created at 2020/10/19 by w10g <br>
 * Initialize HealthExceptionHandler ... <br>
 *
 * @author unknowpupil
 * @since 0.0.1
 */
@RestControllerAdvice
@Slf4j
public class HealthExceptionHandler {

    /**
     * 大异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public ResultResponse handleException(Exception ex) {
        log.error("Exception: {}\n{}", ex.getMessage(), ex);
        String errMsg = ex.getMessage();
        return ResultResponse.buildFailure(ResultStatus.FATAL_ERROR.code(), errMsg);
    }

    /**
     * 运行时异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = RuntimeException.class)
    public ResultResponse handleRuntimeException(RuntimeException ex) {
        log.error("运行时异常 RuntimeException:  {}\n{}", ex.getMessage(), ex);
        String errMsg = ex.getMessage();
        if(StringUtils.isBlank(errMsg)){
            return ResultResponse.buildFailure(ResultStatus.RUNTIME_ERROR, ex);
        }else {
            if(CharUtil.isChinese(errMsg)){
                return ResultResponse.buildFailure(errMsg);
            }else {
                return ResultResponse.buildFailure(ResultStatus.RUNTIME_ERROR, ex);
            }

        }
    }


  // =============================== sql 错误

    /**
     * 数据库异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = SQLException.class)
    public ResultResponse handleSQLException(SQLException ex) {
        log.error("数据库异常 SQLException:  {}\n{}", ex.getMessage(), ex);
        log.error("SQLException Request raised " + ex.getClass().getSimpleName());
        return ResultResponse.buildFailure(ResultStatus.DATABASE_ERROR, ex);
    }




    /**
     * 自定义异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = HealthException.class)
    public ResultResponse handleHealthException(HealthException ex) {
        log.error("自定义异常 HealthException:  {}\n{}", ex.getMessage(), ex);
        String errMsg = ex.getMessage();
        return ResultResponse.buildFailure(ex.getCode(), errMsg);
    }

    /**
     * 连接异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = ConnectException.class)
    public ResultResponse handleConnectException(ConnectException ex) {
        log.error("连接异常 ConnectException:  {}\n{}", ex.getMessage(), ex);
        return ResultResponse.buildFailure(ResultStatus.FAILURE, ex);
    }


    /**
     * 参数异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    public ResultResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException ex) {
        log.error("参数异常 HttpMessageNotReadableException:  {}\n{}", ex.getMessage(), ex);
        return ResultResponse.buildFailure(ResultStatus.PARAM_IS_INVALID, ex);
    }

    /**
     * 空指针异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = NullPointerException.class)
    public ResultResponse handleNullPointerException(NullPointerException ex) {
        log.error("空指针异常 NullPointerException:  {}\n{}", ex.getMessage(), ex);
        return ResultResponse.buildFailure(ResultStatus.FATAL_ERROR, ex);
    }


    /**
     * 客户端异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = HttpClientErrorException.class)
    public ResultResponse handleHttpClientErrorException(HttpClientErrorException ex) {
        log.error("客户端异常 HttpClientErrorException:  {}\n{}", ex.getMessage(), ex);
        return ResultResponse.buildFailure(ResultStatus.FAILURE, ex);
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public ResultResponse handlerNoFoundException(NoHandlerFoundException e) {
        log.error("客户端异常 HttpClientErrorException: {}\n{}", e.getMessage(), e);
        return ResultResponse.buildFailure(ResultStatus.NOT_FOUND, "路径不存在，请检查路径是否正确");
    }

    /**
     * 自定义验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultResponse handleValidExceptionHandler(MethodArgumentNotValidException e) {
        log.error("自定义验证异常 MethodArgumentNotValidException: {}\n{}", e.getMessage(), e);
        String message = e.getBindingResult().getFieldError().getDefaultMessage();
        return ResultResponse.buildFailure(message);
    }


    @ExceptionHandler(AccessDeniedException.class)
    public ResultResponse handleAuthorizationException(AccessDeniedException e) {
        log.error(" AccessDeniedException: {}\n{}", e.getMessage(), e);
        return ResultResponse.buildFailure(ResultStatus.SC_UNAUTHORIZED);
    }

    @ExceptionHandler(AccountExpiredException.class)
    public ResultResponse handleAccountExpiredException(AccountExpiredException e) {
        log.error(" AccountExpiredException: {}\n{}", e.getMessage(), e);
        return ResultResponse.buildFailure(e.getMessage());
    }

    @ExceptionHandler(UsernameNotFoundException.class)
    public ResultResponse handleUsernameNotFoundException(UsernameNotFoundException e) {
        log.error(" UsernameNotFoundException: {}\n{}", e.getMessage(), e);

        return ResultResponse.buildFailure(e.getMessage());
    }
}
